package com.douqu.game.battle.util;

import com.bean.core.util.Utils;
import com.douqu.game.battle.entity.aobject.BattleAObject;
import com.douqu.game.core.astar.AbsCoord;
import com.douqu.game.core.astar.AstarMap;
import com.douqu.game.core.astar.Grid;
import com.douqu.game.core.astar.Node;
import com.douqu.game.core.config.battle.SkillConfig;
import com.douqu.game.core.config.common.CommonData;
import com.douqu.game.core.config.common.Position;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.LogUtils;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2017-10-21 18:49
 */
public class BattleUtils {

    /**
     * 寻路接口
     */
    public static final int GET_ROUTE_PATH = 101;

    public static final boolean TEST_BATTLE = false;
    public static final int ONLY_ENEMY = 0;//敌人出的最大的兵数,只有当上面的TEST_BATTLE为TRUE才有效果
    public static final int[] TEAM1_SKILLS = {};
    public static final int[] TEAM2_SKILLS = {};
    public static final int TEAM1_CARD = 2101;
    public static final int TEAM2_CARD = 1201;
    public static final int TEAM1_MASTER_HP_MUL = 1;
    public static final CommonData[] TEAM2_CRYSTAL_GROW = new CommonData[]{new CommonData(300000, 1000)};

    //二维数组地图以左上对齐方式
    //地图类型1
    public static final int[][] BATTLE_MAP_1 = {
           //0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
            {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},//24
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//23
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//22
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//21
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//20
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//19
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//18
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//17
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//16
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//15
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//14
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//13
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//12
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//11
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//10
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//9
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//8
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//7
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//6
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//5
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//4
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//3
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//2
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},//1
            {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},//0
    };

    public static final int[][] BATTLE_MAP_2 = {
           //0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },//24
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//23
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//22
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//21
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//20
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//19
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//18
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//17
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//16
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//15
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//14
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//13
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//12
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//11
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//10
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//9
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//8
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//7
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//6
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//5
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//4
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//3
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//2
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },//1
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },//0
    };




    /**
     * 获取主英雄旁边附带的英雄位置
     * @param teamNo
     * @param source
     * @return
     */
    public static List<Position> getSoldierSummonPos(AstarMap astarMap, int teamNo, int needCount, Position source, int sourceGridArea, int targetGridArea)
    {
        List<Position> result = new CopyOnWriteArrayList<>();

        final int selfX = source.x;
        final int targetArea = targetGridArea;
        final int selfArea = sourceGridArea;
        LogUtils.debug("targetArea:" + targetArea + " selfArea:" + selfArea);
        boolean left = teamNo == ConstantFactory.BATTLE_TEAM_1 ? selfX > astarMap.width - selfArea - targetArea : selfX > targetArea + selfArea;
        if(left)
        {
            //放在左边
            result.addAll(getLeftPosList(astarMap, source.x-1, source.y, selfArea, targetGridArea, needCount));
            LogUtils.debug("result -> " + result.size());
            if(result.size() < needCount)
            {
                result.addAll(getRightPosList(astarMap, source.x+1, source.y, selfArea, targetGridArea, needCount - result.size()));
            }
            LogUtils.debug("result -> " + result.size());
        }
        else
        {
            //放在右边
            result.addAll(getRightPosList(astarMap, source.x+1, source.y, selfArea, targetGridArea, needCount));
            LogUtils.debug("result -> " + result.size());
            if(result.size() < needCount)
            {
                result.addAll(getLeftPosList(astarMap, source.x-1, source.y, selfArea, targetGridArea, needCount-result.size()));
            }
            LogUtils.debug("result -> " + result.size());
        }

        return result;
    }

//    /**
//     * 获取召唤的兵的位置
//     * @param teamNo
//     * @param source
//     * @param soldier
//     * @return
//     */
//    public static List<Position> getSoldierSummonPos(AstarMap astarMap, int teamNo, int needCount, BattleAObject source, SoldierConfig soldier)
//    {
//        List<Position> result = new CopyOnWriteArrayList<>();
//
//        LogUtils.debug("召唤开始 自己的位置 -> " + source.position + "  needCount -> " + needCount);
//        int selfX = source.position.x;
//        int targetArea = soldier.gridArea;
//        int selfArea = source.getSprite().gridArea;
//        LogUtils.debug("targetArea:" + targetArea + " selfArea:" + selfArea);
//        boolean left = teamNo == ConstantFactory.BATTLE_TEAM_1 ? selfX > astarMap.width - selfArea - targetArea : selfX > targetArea + selfArea;
//        if(left)
//        {
//            //放在左边
//            result.addAll(getLeftPosList(astarMap, source.position.x-1, source.position.y, source.getSprite().gridArea, soldier.gridArea, needCount));
//            LogUtils.debug("result -> " + result.size());
//            if(result.size() < needCount)
//            {
//                result.addAll(getRightPosList(astarMap, source.position.x+1, source.position.y, source.getSprite().gridArea, soldier.gridArea, needCount - result.size()));
//            }
//            LogUtils.debug("result -> " + result.size());
//        }
//        else
//        {
//            //放在右边
//            result.addAll(getRightPosList(astarMap, source.position.x+1, source.position.y, source.getSprite().gridArea, soldier.gridArea, needCount));
//            LogUtils.debug("result -> " + result.size());
//            if(result.size() < needCount)
//            {
//                result.addAll(getLeftPosList(astarMap, source.position.x-1, source.position.y, source.getSprite().gridArea, soldier.gridArea, needCount-result.size()));
//            }
//            LogUtils.debug("result -> " + result.size());
//        }
//
//        return result;
//    }

    private static List<Position> getLeftPosList(AstarMap astarMap, int startX, int selfY, int selfArea, int targetArea, int needCount)
    {
        LogUtils.debug("放在左边 --------------------------------------->startX:" + startX);
        LogUtils.debug("middleObstacleMaxX:" + astarMap.middleObstacleMaxX + " astarMap.middleObstacleMinX:" + astarMap.middleObstacleMinX + " minX:" + astarMap.minX + " minY:" + astarMap.minY);
        List<Position> result = new CopyOnWriteArrayList<>();
        choose:
        for(int i = startX; i >= astarMap.minX; i--)
        {
            if(i > astarMap.maxX)
                continue;

//            if(i <= astarMap.middleObstacleMaxX && i >= astarMap.middleObstacleMinX)
//                continue;

            for(int j = selfY + selfArea; j >= astarMap.minY; j--)
            {
                if(j > astarMap.maxY)
                    continue;

                if(j < targetArea)//不够位置放下要召唤的兵了
                    break;

                if(!astarMap.isObstacleToApplication(i, j))
                {
                    result.add(new Position(i, j));
                    if(result.size() >= needCount)
                        break choose;

                    if(j - targetArea < astarMap.minY)
                        break;

                    j -= targetArea;
                }
            }
        }
        return result;
    }
    private static List<Position> getRightPosList(AstarMap astarMap, int startX, int selfY, int selfArea, int targetArea, int needCount)
    {
        LogUtils.debug("放在右边 --------------------------------------->startX:" + startX);
        LogUtils.debug("middleObstacleMaxX:" + astarMap.middleObstacleMaxX + " astarMap.middleObstacleMinX:" + astarMap.middleObstacleMinX + " maxY:" + astarMap.maxY + " minY:" + astarMap.minY);
        List<Position> result = new CopyOnWriteArrayList<>();
        choose:
        for(int i = startX; i <= astarMap.maxX; i++)
        {
            if(i < astarMap.minX)
                continue;

//            if(i <= astarMap.middleObstacleMaxX && i >= astarMap.middleObstacleMinX)
//                continue;

            for(int j = selfY + selfArea; j >= astarMap.minY; j--)
            {
                if(j > astarMap.maxY)
                    continue;

                if(j < targetArea)//不够位置放下要召唤的兵了
                    break;

                if(!astarMap.isObstacleToApplication(i, j))
                {
                    result.add(new Position(i, j));
                    if(result.size() >= needCount)
                        break choose;

                    if(j - targetArea < astarMap.minY)
                        break;

                    j -= targetArea;
                }
            }
        }
        return result;
    }


    /**
     * 获取士兵出生点
     * @param teamNo
     * @param initRange
     * @param route
     * @param gridArea
     * @return
     */
    public static Position getSoldierBornPos(AstarMap astarMap, int teamNo, int initRange, int route, int gridArea)
    {
        //最大找5次
        int x = 0, y = 0;
        int middleObstacleMinX = astarMap.middleObstacleMinX;
        for(int i = 0; i < 5; i++)
        {
            int r1 = Utils.getRandom(initRange > middleObstacleMinX - gridArea ? middleObstacleMinX - gridArea : initRange);
            r1 = r1 < 1 ? 1: r1;
            int temp = (astarMap.height - 1)>>1;
            int r2 = Utils.getRandom(temp);

            if(teamNo == ConstantFactory.BATTLE_TEAM_1)
                x = r1;
            else
                x = astarMap.width - 1 - r1;

            if(route == 0)
                route = Utils.getRandom(2) == 0 ? ConstantFactory.ROUTE_BOTTOM : ConstantFactory.ROUTE_TOP;
            if(route == ConstantFactory.ROUTE_TOP)
                y = temp + r2;
            else
                y = r2;

            if(!astarMap.isObstacleToApplication(x, y))
                break;
        }

        if(x == 0 || y == 0)
        {
            return BattleUtils.getSoldierPos(astarMap, teamNo, route, gridArea);
        }

        return new Position(x, y);
    }

    /**
     * 修复坐标超出 边界
     * @param astarMap
     * @param position
     */
    public static void fixSoldierPositionBorder(AstarMap astarMap, Position position)
    {
        position.x = astarMap.fixBorderX(position.x);
        position.y = astarMap.fixBorderY(position.y);
    }

    public static boolean fixSoldierPosition(int teamNo, AstarMap astarMap, Position position)
    {
        Grid grid = astarMap.fixSoldierPosition(teamNo, position.x, position.y);
        if(grid == null)
            return false;

        position.x = grid.x;
        position.y = grid.y;

        return true;
    }

    public static List<Node> changePositionToNode(List<Position> list)
    {
        List<Node> result = new ArrayList<>();
        for(Position position : list)
        {
            result.add(new Node(position.x, position.y));
        }
        return result;
    }


    public static List<Position> changeRoute(List list, float speed)
    {
        if(speed == 0)
            return list;

        int size = list.size();
        List<Position> sourceRoute = new CopyOnWriteArrayList<>();
        for(int i = 0; i < size; i++){
            if(list.get(i) instanceof Position)
                sourceRoute.add((Position) list.get(i));
            else if(list.get(i) instanceof SGCommonProto.Pos)
                sourceRoute.add(new Position((SGCommonProto.Pos) list.get(i)));
            else if(list.get(i) instanceof Node)
                sourceRoute.add(new Position(((Node)list.get(i)).grid.x, ((Node) list.get(i)).grid.y));
            else if(list.get(i) instanceof AbsCoord)
                sourceRoute.add(new Position(((AbsCoord)list.get(i)).x, ((AbsCoord) list.get(i)).y));
            else
            {
                LogUtils.warn("参数错误:" + list);
                return list;
            }
        }

        Map<Integer, Float> distanceMap = new HashMap<>();
        Position p1 = null;
        List<Position> result = new CopyOnWriteArrayList<>();
        if(size <= 2)
        {
            for(int i = 0; i < size; i++){
                result.add(sourceRoute.get(i));
            }
        }
        else
        {
            float totalDistance = 0;
            for(int i = 0; i < size; i++){
                if(i > 0){
                    totalDistance += getDistance(sourceRoute.get(i), sourceRoute.get(i - 1));
                }
                distanceMap.put(i, totalDistance);
            }

            int count = (int)(totalDistance /(speed * 0.5));

            Position lastPosition = sourceRoute.get(size-1);
            Position tempPosition = null;
            boolean isAddLast = false;

            for(int i = 0; i < count; i++){
                //i * speed * 0.5f 表示 这一帆应该走多少距离
                tempPosition = changePoint(sourceRoute, i * speed * 0.5f, distanceMap);
                result.add(tempPosition);

                if(i == count - 1)
                {
                    //是否添加了最后一个点
                    isAddLast = tempPosition.isSame(lastPosition);
                }
            }

            if(!isAddLast)
                result.add(lastPosition);
        }

        return result;
    }





    private static Position changePoint(List<Position> routeList, float distance, Map<Integer, Float> distanceMap)
    {
        int size = routeList.size();
        for(int i = 1; i < size ; i++){
            if(distance < distanceMap.get(i))
            {
                if(i == size - 1){
                    return routeList.get(i);
                }else {
                    Position beforePosition = routeList.get(i - 1);
                    Position tempPosition = routeList.get(i);
                    float offsetNowPoint = distance - distanceMap.get(i-1);
                    float rat = offsetNowPoint / getDistance(tempPosition, beforePosition);
                    return new Position(beforePosition.getX() + rat * (tempPosition.getX() - beforePosition.getX()), beforePosition.getY() + rat * (tempPosition.getY() - beforePosition.getY()));
                }
            }
        }
        return null;
    }


    public static BattleAObject getMinHPUnit(List<BattleAObject> targets)
    {
        return Collections.min(targets, new Comparator<BattleAObject>() {
            @Override
            public int compare(BattleAObject o1, BattleAObject o2) {
                return new Long(o1.getHp()).compareTo(o2.getHp());
            }
        });
    }

    public static BattleAObject getMaxAtkUnit(List<BattleAObject> targets)
    {
        return Collections.max(targets, new Comparator<BattleAObject>() {
            @Override
            public int compare(BattleAObject o1, BattleAObject o2) {
                return new Long(o1.atk.getAtt()).compareTo(o2.atk.getAtt());
            }
        });
    }

    public static BattleAObject getMaxDefUnit(List<BattleAObject> targets)
    {
        return Collections.max(targets, new Comparator<BattleAObject>() {
            @Override
            public int compare(BattleAObject o1, BattleAObject o2) {
                return new Long(o1.def.getAtt()).compareTo(o2.def.getAtt());
            }
        });
    }


    /**
     * 是否在攻击范围内
     * @param source
     * @param target
     * @return
     */
    public static boolean isInAtkRange(BattleAObject source, BattleAObject target, SkillConfig skillConfig)
    {
        float ax = source.position.getX();
        float ay = source.position.getY();
        float bx = target.position.getX();
        float by = target.position.getY();
        float distance = BattleUtils.getDistance(source.position, target.position);
        if(distance > skillConfig.atkRange)
        {
            float aax = ax + (source.getSprite().gridArea - 1) / distance * (bx - ax);
            float aay = ay + (source.getSprite().gridArea - 1) / distance * (by - ay);
            float bbx = bx + (target.getSprite().gridArea - 1) / distance * (ax - bx);
            float bby = by + (target.getSprite().gridArea - 1) / distance * (ay - by);

            return BattleUtils.isInCircleRange(new Position(aax, aay), new Position(bbx, bby), skillConfig.atkRange);
        }
        else
        {
            return true;
        }
    }

    /**
     * 检测是否在矩形攻击范围内
     * @param source 攻击者
     * @param targetPosition 要检测是否在攻击范围内的目标
     * @param directionPoint 最初的攻击参考者
     * @param atkRange
     * @param width
     * @param height
     * @return
     */
    public static boolean isInDamageRangeByRectangle(BattleAObject source, Position targetPosition, int targetGridArea, Position directionPoint, int atkRange, int width, int height)
    {
        float ax = source.position.x;
        float ay = source.position.y;
        float bx = targetPosition.x;
        float by = targetPosition.y;
        float distance = BattleUtils.getDistance(source.position, targetPosition);
        LogUtils.debug("distance -> " + distance + "  atkRange -> " + atkRange + " source:" + source.position + " targetPosition:" + targetPosition);
        if(distance > atkRange)
        {
            //加上模型大小来检测
            float aax = ax + (source.getSprite().gridArea - 1) / distance * (bx - ax);
            float aay = ay + (source.getSprite().gridArea - 1) / distance * (by - ay);
            float bbx = bx + (targetGridArea - 1) / distance * (ax - bx);
            float bby = by + (targetGridArea - 1) / distance * (ay - by);

            LogUtils.debug("aax:" + aax + ",aay:" + aay + " bbx:" + bbx + ",bby:" + bby + " directionPoint -> " + directionPoint);
            Position newSource = new Position(aax, aay);
            Position newCheck = new Position(bbx, bby);
            if(newSource.isSame(newCheck))
                return BattleUtils.isInRectangleByBorder(source.position, targetPosition, directionPoint, width, height, true);
            else
                return BattleUtils.isInRectangleByBorder(newSource, newCheck, directionPoint, width, height, true);
        }
        else
        {
            return true;
        }
    }

    /**
     * 检测扇形伤害范围
     * @param source 攻击者
     * @param targetPosition 要检测是否在攻击范围内的目标
     * @param directionPoint 最初的攻击参考者
     * @param atkRange
     * @param radius
     * @param angle
     * @return
     */
    public static boolean isInDamageRangeBySector(BattleAObject source, Position targetPosition, int targetGridArea, Position directionPoint, int atkRange, int radius, int angle)
    {
        float ax = source.position.x;
        float ay = source.position.y;
        float bx = targetPosition.x;
        float by = targetPosition.y;
        float distance = BattleUtils.getDistance(source.position, targetPosition);
        if(distance > atkRange)
        {
            float aax = ax + (source.getSprite().gridArea - 1) / distance * (bx - ax);
            float aay = ay + (source.getSprite().gridArea - 1) / distance * (by - ay);
            float bbx = bx + (targetGridArea - 1) / distance * (ax - bx);
            float bby = by + (targetGridArea - 1) / distance * (ay - by);

            Position newSource = new Position(aax, aay);
            Position newCheck = new Position(bbx, bby);
            if(newSource.isSame(newCheck))
                return BattleUtils.isInSector(source.position, targetPosition, directionPoint, radius, angle, true);
            else
                return BattleUtils.isInSector(newSource, newCheck, directionPoint, radius, angle, true);
        }
        else
        {
            return true;
        }
    }



    /**
     * 获取两点的距离
     * @param source
     * @param target
     * @return
     */
    public static float getDistance(Position source, Position target)
    {
        return (float) Math.abs(Math.sqrt(Math.pow((source.getX() - target.getX()), 2) + Math.pow((source.getY() - target.getY()), 2)));
    }

    /**
     * 获取两点的距离
     * @param source
     * @param target
     * @return
     */
    public static float getDistance(SGCommonProto.Pos source, SGCommonProto.Pos target)
    {
        return (float) Math.abs(Math.sqrt(Math.pow((source.getX() - target.getX()), 2) + Math.pow((source.getY() - target.getY()), 2)));
    }

    public static boolean checkPoint(Position leftTop, Position rightBottom, Position target){
        boolean in = false;
        if(target.getX() <= rightBottom.getX() && target.getX() >= leftTop.getX()
                && target.getY() <= leftTop.getY() && target.getY() >= rightBottom.getY()){
            in = true;
        }
        return in;
    }


    /**
     * 坐标转换成标准XY轴的
     * @param A
     * @param sinVale
     * @return
     */
    public static Position switchPoint(Position A, float sinVale){
        return new Position(A.y * sinVale, -A.x * sinVale);
    }
    /**
     * 坐标转换成标准XY轴的
     * @param A
     * @param sinVale
     * @param cosVale
     * @param tanVale
     * @return
     */
    public static Position switchPoint(Position A, float sinVale, float cosVale,float tanVale){
        float x = A.getX() / cosVale  + (A.getY() - A.getX() * tanVale) * sinVale;
        float y = A.getY() * cosVale - A.getX() * sinVale;
        return new Position(x, y);
    }


    /**
     * 检测目标是否在某个坐标的圆形攻击范围内
     * @param source 检测对象
     * @param target 要检测的目标
     * @param range 范围
     * @return
     */
    public static boolean isInCircleRange(Position source, Position target, int range)
    {
        if(range == 0)
            return true;

        // 两点间距离公式
        float result = getDistance(source, target);

        int temp = (int) result;
        return temp <= range;
    }


    /**
     * 以参考点在中心判断矩形
     * @param sourcePoint
     * @param directionPoint
     * @param checkPoint
     * @param width
     * @param height
     * @return
     */
    public static boolean isInRectangleByCenter(Position sourcePoint, Position directionPoint, Position checkPoint, int width, int height)
    {
        float r = (float) Math.sqrt(Math.pow(sourcePoint.getX() - directionPoint.getX(), 2) + Math.pow(sourcePoint.getY() - directionPoint.getY(), 2));
        float cosVale = (directionPoint.getX() - sourcePoint.getX()) / r;
        float sinVale = (directionPoint.getY() - sourcePoint.getY()) / r;
        //把起点坐标转换
        Position sA = null;
        //把要检测的点转换一个坐标
        Position sP = null;
        if(directionPoint.x == sourcePoint.x)
        {
            sA = switchPoint(sourcePoint, sinVale);
            sP = switchPoint(checkPoint, sinVale);
        }
        else
        {
            float tanVale = (directionPoint.getY() - sourcePoint.getY()) / (directionPoint.getX() - sourcePoint.getX());
            sA = switchPoint(sourcePoint, sinVale, cosVale, tanVale);
            sP = switchPoint(checkPoint, sinVale, cosVale, tanVale);
        }

        Position leftTop = new Position(sA.getX() - (width>>1), sA.getY() + (width>>2));
        Position rightBottom = new Position(sA.getX() + (height>>1), sA.getY() - (width>>2));

        return checkPoint(leftTop, rightBottom, sP);
    }

    /**
     * 检测矩形范围,以矩形的一条边的中间点为起点
     * A打B,B旁边有个C,
     * 检测B是否在攻击范围内时 -> sourcePoint是A的坐标,directionPoint是B的坐标,checkPoint是B的坐标
     * 检测C是否在攻击范围内时 -> sourcePoint是A的坐标,directionPoint是B的坐标,checkPoint是C的坐标
     * @param sourcePoint 攻击者的坐标　
     * @param directionPoint 攻击参考点的坐标
     * @param checkPoint 要检测是否在攻击范围内的目标的坐标
     * @param width 长
     * @param height 宽
     * @param height 宽
     * @param sourceStart 是否是以source为起点
     */
    public static boolean isInRectangleByBorder(Position sourcePoint, Position checkPoint, Position directionPoint, int width, int height, boolean sourceStart)
    {
        if(sourcePoint.isSame(checkPoint))
            return true;

        if(sourcePoint.isSame(directionPoint))
        {
            //参考点和自己是同一个位置，计算距离
            return getDistance(sourcePoint, checkPoint) < Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
        }

        float r = (float) Math.sqrt(Math.pow(sourcePoint.getX() - directionPoint.getX(), 2) + Math.pow(sourcePoint.getY() - directionPoint.getY(), 2));
        float cosVale = (directionPoint.getX() - sourcePoint.getX()) / r;
        cosVale = sourceStart ? cosVale : -cosVale;
        float sinVale = (directionPoint.getY() - sourcePoint.getY()) / r;
        sinVale = sourceStart ? sinVale : -sinVale;
        //把起点坐标转换
        Position sA = null;
        //把要检测的点转换一个坐标
        Position sP = null;
        if(directionPoint.x == sourcePoint.x)
        {
            sA = switchPoint(sourcePoint, sinVale);
            sP = switchPoint(checkPoint, sinVale);
        }
        else
        {
            float tanVale = (directionPoint.getY() - sourcePoint.getY()) / (directionPoint.getX() - sourcePoint.getX());
            sA = switchPoint(sourcePoint, sinVale, cosVale, tanVale);
            sP = switchPoint(checkPoint, sinVale, cosVale, tanVale);
        }

        Position leftTop = new Position(sA.getX(), sA.getY() + (width>>1));
        Position rightBottom = new Position(sA.getX() + height, sA.getY() - (width>>1));

        LogUtils.debug("leftTop -> " + leftTop + " rightBottom -> " + rightBottom + " sp -> " + sP + " sourcePoint -> " + sourcePoint + " directionPoint -> " + directionPoint + " checkPoint -> " + checkPoint + " width -> " + width + " height -> " + height + " sourceStart -> " + sourceStart);
        return checkPoint(leftTop, rightBottom, sP);
    }

    /**
     * 是否在扇形内
     * * A打B,B旁边有个C,
     * 检测B是否在攻击范围内时 -> sourcePoint是A的坐标,directionPoint是B的坐标,checkPoint是B的坐标
     * 检测C是否在攻击范围内时 -> sourcePoint是A的坐标,directionPoint是B的坐标,checkPoint是C的坐标
     * @param sourcePoint 攻击者的坐标　
     * @param directionPoint 攻击参考点的坐标
     * @param checkPoint 要检测是否在攻击范围内的目标的坐标
     * @param radius
     * @param angle 角度必须在90度以内 ,大于0度
     * @param sourceStart 是否是以source为起点
     * @return
     */
    public static boolean isInSector(Position sourcePoint, Position checkPoint, Position directionPoint, int radius, int angle, boolean sourceStart)
    {
        //检测距离
        if(getDistance(sourcePoint, checkPoint) > radius)
            return false;

        if(checkPoint.getX() == (sourceStart ? sourcePoint.getX() : directionPoint.getX()))
            return true;

        //到检测点的距离
        float distance = getDistance(sourcePoint, directionPoint);
        float sinVale = (directionPoint.getY() - sourcePoint.getY()) / distance;
        float cosVale = (directionPoint.getX() - sourcePoint.getX()) / distance;
        float tanVale = 0;
        //检测点转换坐标
        Position checkSwitchPoint = null;
        Position startSwitchPoint = null;
        if(directionPoint.x == sourcePoint.x)
        {
            checkSwitchPoint = switchPoint(checkPoint, sinVale);
            if(sourceStart)
            {
                //起点转换坐标,转换成中间线重合X轴
                startSwitchPoint = switchPoint(sourcePoint, sinVale);
            }
            else
            {
                startSwitchPoint = switchPoint(directionPoint, sinVale);
            }
        }
        else
        {
            tanVale = (directionPoint.getY() - sourcePoint.getY()) / (directionPoint.getX() - sourcePoint.getX());
            checkSwitchPoint = switchPoint(checkPoint, sinVale, cosVale, tanVale);
            if(sourceStart)
            {
                //起点转换坐标,转换成中间线重合X轴
                startSwitchPoint = switchPoint(sourcePoint, sinVale, cosVale, tanVale);
            }
            else
            {
                startSwitchPoint = switchPoint(directionPoint, sinVale, cosVale, tanVale);
            }
        }


        //角度转弧度
        float radian = (float) ((angle>>1)*Math.PI/180);
        float max = (float) Math.tan(radian);
        //斜率
        float K = (checkSwitchPoint.getY() - startSwitchPoint.getY()) / (checkSwitchPoint.getX() - startSwitchPoint.getX());
        return K >= -max && K <= max;
    }



    /**
     * 取一个默认的士兵出生位置
     * @return
     */
    public static Position getSoldierPos(AstarMap astarMap, int teamNo, int route, int gridArea)
    {
        if(teamNo == ConstantFactory.BATTLE_TEAM_1)
        {
            for(int i = gridArea; i < astarMap.width; i++)
            {
                if(route == ConstantFactory.ROUTE_TOP)
                {
                    for(int j = astarMap.height-gridArea; j > 0; j--)
                    {
                        if(!astarMap.isObstacleToApplication(i, j))
                            return new Position(i, j);
                    }
                }
                else
                {
                    for(int j = gridArea; j < astarMap.height; j++)
                    {
                        if(!astarMap.isObstacleToApplication(i, j))
                            return new Position(i, j);
                    }
                }
            }
        }
        else if(teamNo == ConstantFactory.BATTLE_TEAM_2)
        {
            for(int i = astarMap.width-gridArea; i > 0; i--)
            {
                if(route == ConstantFactory.ROUTE_TOP)
                {
                    for(int j = astarMap.height-gridArea; j > 0; j--)
                    {
                        if(!astarMap.isObstacleToApplication(i, j))
                            return new Position(i, j);
                    }
                }
                else
                {
                    for(int j = gridArea; j < astarMap.height; j++)
                    {
                        if(!astarMap.isObstacleToApplication(i, j))
                            return new Position(i, j);
                    }
                }
            }
        }

        return null;
    }





    public static void main(String[] args)
    {

        int a = 0;
        byte b1 = 99;
        short b2 = 99;
        int b3 = 99;
        long b4 = 99;
        float b = a;

        byte c1 = (byte) (b1 / b);

        short c2 = (short) (b2 / b);

        int c3 = (int) (b3 / b);

        long c4 = (long) (b4 / b);

        System.out.println("c1 -> " + c1);
        System.out.println("c2 -> " + c2);
        System.out.println("c3 -> " + c3);
        System.out.println("c4 -> " + c4);
    }



}
